package dletc.demo;

import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;

/**
 * 泛型 https://blog.csdn.net/qq_41701956/article/details/123473592 参考资料：
 *  1.JDK5.0之后推出的新特性泛型
 *  2.泛型这种语法机制，只在程序编译阶段起作用，只是给编译器参考的。（运行阶段泛型没用！）
 *  3.使用了泛型好处是什么？
 *      第一：集合中存储的元素类型统一了,数据安全性。
 *      第二：从集合中取出的元素类型是泛型指定的类型，不需要进行大量的“向下转型”
 *  4.泛型的缺点是什么？
 *      导致集合中存储的元素缺乏多样性。
 *      大多数业务中，集合中元素的类型还是统一的，所以这种泛型机制特性被大家所认可。
 *  5.JDK8之后引入了：自动类型推断机制（又称为砖石表达式）
 *      new对象时，后面的泛型可以空着不写。
    6 泛型的应用：
      	1） 在集合中使用泛型：
              A 泛型的使用 规则： 泛型必须是一个类（引用数据类型），例如String,Person , 包装类
              B 如果创建集合的时候不指定泛型，那么集合数据默认为Object类型
 		2) 在类、接口中使用（泛型类，泛型接口）
                             格式：public class Other<T> {
                     }
           	注意：类内部的成员都可以使用泛型： 成员变量，成员方法，返回值类型 ，参数都可以
            A 创建对象的时候指定泛型类的数据类型
            	Other<String> o1 = new Other<>();
            B 继承关系的时候，有两种情况
                1）如果子类在继承父类的时候，父类已经指定泛型了,那么子类创建对象的时候不需要指定泛型
                2) 如果子类在继承父类的时候，父类未指定泛型了,那么子类创建对象的时需要指定泛型
    7.泛型类、泛型接口注意事项：
 		1）JDK1.7之后后面的泛型可以省略：
                   SubOther2<String> so2 = new SubOther2<>();
        2）泛型类可以有多个参数：public class Other<T, E, K,V>{
        3)不可以在泛型类的构造器上写泛型,但是构造器的方法参数位置可以用
               public Other<T>(){ }//错误
        4）泛型不同的集合是不能相互赋值的
          ArrayList<String>  list1 = new ArrayList<>();
		  ArrayList<Integer> list2 = new ArrayList<>();
		  list1 = list2; 报错
     	5）静态方法中不能够使用泛型:
 				一旦被静态修饰的话 他就要类加载的时候先加载 泛型是创建对象的时候去指定
     	6) 自定义异常类不能使用泛型：
			   //不可以这么写报错
			   public class MyException<T> extends Exception{}
        7）不能创建泛型数组
            T[] t = new T[10];//不可以
    		T[] t = (T[])new Object[10]; 可以
    8.泛型在方法上的应用，在权限修饰符和返回值之间使用泛型，声明该方法为泛型方法
   		语法： public <E> void method(){}
   	9.泛型的通配符：? [可以代表所有的数据类型]
 */

public class Demo01 {
	//当没有想好是什么数据类型时，可以使用泛型。
    public static void main(String[] args) {
		//ArrayList<这里面的类型会自动推断> JDK8之后的新特性，才允许。
        List<String> list = new ArrayList<>();
        //list.add(123); 数据类型与泛型不匹配。
        list.add("123");

		Other o1 = new Other();
        
        Integer[] integer = new Integer[]{1,2,3,4,5,6,7};
        
        //调用带有泛型的方法，通过传参的时候去指定泛型的数据类型。
        ArrayList<Integer> copyList = o1.copyList(integer);
        
        System.out.println(copyList);
    }
}

